
package com.yishe.redis;


import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisClientConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;

import java.io.Serializable;

/**
 * create by: chusifeng
 * Create in 2021/4/28 14:58
 * Description:
 * @author
 * <p>Example</p>
 */
@Slf4j
@Configuration 
@EnableAutoConfiguration
public class SingleRedisConfig { 
	
	@Value(value = "${spring.redis.hostName}")
	private String hostName;
	@Value(value = "${spring.redis.port}")
	private String port;
	@Value(value = "${spring.redis.password}")
	private String password;
	
	@Bean
	public JedisPoolConfig getRedisConfig() {
		JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
		//最大连接数
		jedisPoolConfig.setMaxTotal(100);
		//最小空闲连接数
		jedisPoolConfig.setMinIdle(20);
		//当池内没有可用的连接时，最大等待时间
		jedisPoolConfig.setMaxWaitMillis(10000);
		//------其他属性根据需要自行添加-------------

		return jedisPoolConfig;
	}
 
	@Bean 
	public RedisConnectionFactory jedisConnectionFactory( JedisPoolConfig jedisPoolConfig) {
		//单机版jedis
		RedisStandaloneConfiguration redisStandaloneConfiguration =
			new RedisStandaloneConfiguration();
		//设置redis服务器的host或者ip地址
		redisStandaloneConfiguration.setHostName(hostName);
		//设置密码
		redisStandaloneConfiguration.setPassword(RedisPassword.of(password));
		//设置redis的服务的端口号
		redisStandaloneConfiguration.setPort(Integer.parseInt(port));
		JedisClientConfiguration.JedisPoolingClientConfigurationBuilder  jpcb =
			(JedisClientConfiguration.JedisPoolingClientConfigurationBuilder)JedisClientConfiguration.builder();
		jpcb.poolConfig(jedisPoolConfig);
		JedisClientConfiguration jedisClientConfiguration = jpcb.build();


		log.info(" ----- single redis config hostName {}" ,hostName);
		log.info(" ----- single redis config port {}" ,port); 
		return new JedisConnectionFactory(redisStandaloneConfiguration, jedisClientConfiguration);
	}

	/**
	 * 实例化 RedisTemplate 对象
	 *
	 * @author jiangwy
	 * @date 2019年9月11日下午7:02:12
	 * @param redisConnectionFactory
	 * @return
	 */
	@Bean
	public RedisTemplate<Serializable, Object> functionDomainRedisTemplate(
			RedisConnectionFactory redisConnectionFactory) {
		RedisTemplate<Serializable, Object> redisTemplate = new RedisTemplate<Serializable, Object>();
		initDomainRedisTemplate(redisTemplate, redisConnectionFactory);
		return redisTemplate;
	}

	/**
	 * 设置数据存入 redis 的序列化方式,并开启事务
	 * 
	 * @author jiangwy
	 * @date 2019年9月11日下午7:02:12
	 * @param redisTemplate
	 * @param factory
	 */
	private void initDomainRedisTemplate(RedisTemplate<Serializable, Object> redisTemplate,
			RedisConnectionFactory factory) {
		// 如果不配置Serializer，那么存储的时候缺省使用String，如果用User类型存储，那么会提示错误User can't cast
		// to String！
		redisTemplate.setKeySerializer(new StringRedisSerializer());
		redisTemplate.setHashKeySerializer(new StringRedisSerializer());
		redisTemplate.setHashValueSerializer(new JdkSerializationRedisSerializer());
		redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
		// 开启事务
		redisTemplate.setEnableTransactionSupport(false);
		redisTemplate.setConnectionFactory(factory);
		log.info(" ----- single redis config   ======== Transaction init over.");
	}


	@Bean
	public RedisUtils redisUtils(RedisTemplate functionDomainRedisTemplate) {
		RedisUtils redisUtils = RedisUtils.getInstance();
		redisUtils.setRedisTemplate(functionDomainRedisTemplate);
		log.info(" ----- single redis config  ======== redisTemplate init over.");
		return redisUtils;
	}

}